#include "RenderMesh.h"
#include <fstream>
using std::ifstream;

// Default Constructor - Initialize data members to safe values
RenderMesh::RenderMesh(void)
{
	m_pVertexBuff	= nullptr;
	m_pIndexBuff	= nullptr;
	m_pVertexDecl	= nullptr;
	m_uiVertSize	= 0;
	m_uiNumVerts	= 0;
	m_uiPrimCount	= 0;
}

// Function used to load the mesh from a file
void RenderMesh::Load(const char* filename)
{
	if(filename)
	{
		// TODO: Load Mesh from the file
		ifstream in;

		in.open(filename, std::ios_base::in | std::ios_base::binary);
		if(in.is_open())
		{
			// Load mesh


			in.close();
		}
	}
	else
	{
		// Default shape if no filename to load
		MakeCube();
	}
}

// For test purposes, we might want to just make a hardcoded cube...
void RenderMesh::MakeCube(void)
{
	// Hardcoded cube!
#pragma region UGLY_CODE
	m_pVertexDecl = g_VertPosTex;
	m_uiNumVerts = 24;
	m_uiPrimCount = 12;
	m_uiVertSize = sizeof(VERT_POS_TEX);

	VERT_POS_TEX* verts = new VERT_POS_TEX[m_uiNumVerts];
	verts[0].pos = D3DXVECTOR3(-1, 1, -1);
	verts[1].pos = D3DXVECTOR3(1, 1, -1);
	verts[2].pos = D3DXVECTOR3(1, -1, -1);
	verts[3].pos = D3DXVECTOR3(-1, -1, -1);

	verts[0].uvs = D3DXVECTOR2(0,0);
	verts[1].uvs = D3DXVECTOR2(1,0);
	verts[2].uvs = D3DXVECTOR2(1,1);
	verts[3].uvs = D3DXVECTOR2(0,1);

	verts[4].pos = D3DXVECTOR3(-1, 1, 1);
	verts[5].pos = D3DXVECTOR3(-1, -1, 1);
	verts[6].pos = D3DXVECTOR3(1, -1, 1);
	verts[7].pos = D3DXVECTOR3(1, 1, 1);

	verts[7].uvs = D3DXVECTOR2(0,0);
	verts[4].uvs = D3DXVECTOR2(1,0);
	verts[5].uvs = D3DXVECTOR2(1,1);
	verts[6].uvs = D3DXVECTOR2(0,1);

	verts[8].pos = D3DXVECTOR3(-1, 1, -1);
	verts[9].pos = D3DXVECTOR3(-1, -1, -1);
	verts[10].pos = D3DXVECTOR3(-1, -1, 1);
	verts[11].pos = D3DXVECTOR3(-1, 1, 1);

	verts[11].uvs = D3DXVECTOR2(0,0);
	verts[8].uvs = D3DXVECTOR2(1,0);
	verts[9].uvs = D3DXVECTOR2(1,1);
	verts[10].uvs = D3DXVECTOR2(0,1);

	verts[12].pos = D3DXVECTOR3(1, 1, -1);
	verts[13].pos = D3DXVECTOR3(1, 1, 1);
	verts[14].pos = D3DXVECTOR3(1, -1, 1);
	verts[15].pos = D3DXVECTOR3(1, -1, -1);

	verts[12].uvs = D3DXVECTOR2(0,0);
	verts[13].uvs = D3DXVECTOR2(1,0);
	verts[14].uvs = D3DXVECTOR2(1,1);
	verts[15].uvs = D3DXVECTOR2(0,1);

	verts[16].pos = D3DXVECTOR3(-1, 1, -1);
	verts[17].pos = D3DXVECTOR3(-1, 1, 1);
	verts[18].pos = D3DXVECTOR3(1, 1, 1);
	verts[19].pos = D3DXVECTOR3(1, 1, -1);

	verts[17].uvs = D3DXVECTOR2(0,0);
	verts[18].uvs = D3DXVECTOR2(1,0);
	verts[19].uvs = D3DXVECTOR2(1,1);
	verts[16].uvs = D3DXVECTOR2(0,1);

	verts[20].pos = D3DXVECTOR3(-1, -1, -1);
	verts[21].pos = D3DXVECTOR3(1, -1, -1);
	verts[22].pos = D3DXVECTOR3(1, -1, 1);
	verts[23].pos = D3DXVECTOR3(-1, -1, 1);

	verts[20].uvs = D3DXVECTOR2(0,0);
	verts[21].uvs = D3DXVECTOR2(1,0);
	verts[22].uvs = D3DXVECTOR2(1,1);
	verts[23].uvs = D3DXVECTOR2(0,1);

	UINT indices[] =
	{
		0,1,3,
		3,1,2,
		4,5,7,
		7,5,6,
		8,9,11,
		11,9,10,
		12,13,15,
		15,13,14,
		16,17,19,
		19,17,18,
		20,21,23,
		23,21,22
	};

	m_pVertexBuff = RENDERER->CreateVertexBuffer(verts, sizeof(VERT_POS_TEX) * m_uiNumVerts);
	m_pIndexBuff = RENDERER->CreateIndexBuffer(indices, sizeof(UINT) * m_uiPrimCount * 3);
#pragma endregion
}

// This will set the vertex declaration and stream sources for the renderer to render this mesh
void RenderMesh::Render(void)
{
	RENDERER->SetVertexDeclaration(m_pVertexDecl);
	RENDERER->SetStreamSource(m_pVertexBuff, m_uiVertSize);
	RENDERER->SetIndices(m_pIndexBuff);
	RENDERER->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, m_uiNumVerts, m_uiPrimCount);
}